package handler

import (
	"fmt"
	"gitee.com/mangenotwork/game-douniu/api/dao"
	"gitee.com/mangenotwork/game-douniu/api/entity"
	"github.com/mangenotwork/common/log"
	"github.com/mangenotwork/common/utils"
	"sync"
)

var Room sync.Map

func GetRoomTotal() int64 {
	var total int64 = 0
	Room.Range(func(key, value any) bool {
		total++
		return true
	})
	return total
}

// 创建房间
func RoomAdd(roomId, userId int64) {
	roomData := &entity.RoomState{
		RoomId:    roomId,
		Homeowner: userId,
		UserList:  make([]*entity.RoomUserState, 0),
		State:     0,
	}
	roomKey := utils.AnyToString(roomId)
	Room.Store(roomKey, roomData)
}

// 玩家加入房间
func RoomJoin(roomId, userId int64) (bool, error) {
	user, err := new(dao.UserDao).GetUser(userId)
	if err != nil {
		log.Error("获取用户信息失败", err)
		return false, err
	}
	roomKey := utils.AnyToString(roomId)
	roomData, ok := Room.Load(roomKey)
	if !ok {
		return ok, fmt.Errorf("房间不存在")
	}
	roomDataObj, ok := roomData.(*entity.RoomState)
	if !ok {
		return ok, fmt.Errorf("房间不存在")
	}

	if roomDataObj.State == 2 {
		// 房间已开始游戏
		return false, fmt.Errorf("房间已开始游戏")
	}

	for _, v := range roomDataObj.UserList {
		if v.UserId == userId {
			return false, fmt.Errorf("已在房间")
		}
	}

	roomDataObj.UserList = append(roomDataObj.UserList, &entity.RoomUserState{
		UserId:   userId,
		NickName: user.NickName,
		Avatar:   user.Avatar,
		State:    0, // 1:玩家准备 非1:未准备
	})
	// 更新数据
	Room.Store(roomKey, roomDataObj)

	// todo 更新持久化数据

	return true, nil
}

// todo  从持久化中恢复房间
func RestoreRoom() {

}

// 玩家准备1,  玩家取消准备0
func RoomUserReady(roomId, userId, readyType int64) bool {
	roomKey := utils.AnyToString(roomId)
	roomData, ok := Room.Load(roomKey)
	if !ok {
		return ok
	}
	roomDataObj, ok := roomData.(*entity.RoomState)
	if !ok {
		return ok
	}
	for i := 0; i < len(roomDataObj.UserList); i++ {
		if roomDataObj.UserList[i].UserId == userId {
			roomDataObj.UserList[i].State = readyType
		}
	}
	// 更新数据
	Room.Store(roomKey, roomDataObj)
	return true
}

// 玩家退出房间
func RoomOut(roomId, userId int64) bool {
	roomKey := utils.AnyToString(roomId)
	roomData, ok := Room.Load(roomKey)
	if !ok {
		return ok
	}
	roomDataObj, ok := roomData.(*entity.RoomState)
	if !ok {
		return ok
	}
	for i := 0; i < len(roomDataObj.UserList); i++ {
		if roomDataObj.UserList[i].UserId == userId {
			roomDataObj.UserList = append(roomDataObj.UserList[:i], roomDataObj.UserList[i+1:]...)
		}
	}
	// 更新数据
	Room.Store(roomKey, roomDataObj)
	return true
}

// 获取房间数据 - 包含用户准备数据
func RoomData(roomId int64) (*entity.RoomState, error) {
	var (
		roomDataObj = &entity.RoomState{}
	)

	roomKey := utils.AnyToString(roomId)
	roomData, ok := Room.Load(roomKey)
	if !ok {
		return roomDataObj, fmt.Errorf("房间不存在")
	}
	roomDataObj, ok = roomData.(*entity.RoomState)
	if !ok {
		return roomDataObj, fmt.Errorf("房间不存在")
	}

	//// 3是开始游戏
	//if roomDataObj.State != 3 {
	//	state := 1
	//	userCount := 0
	//	// 检查准备状态
	//	for _, v := range roomDataObj.UserList {
	//		userCount++
	//		if v.State != 1 {
	//			state = 0
	//			break
	//		}
	//	}
	//	if userCount < 2 {
	//		state = 0
	//	}
	//	roomDataObj.State = int64(state)
	//}
	// 更新数据
	Room.Store(roomKey, roomDataObj)
	return roomDataObj, nil
}

// 解散房间
func RoomDissolution(roomId int64) error {
	roomDataObj := &entity.RoomState{}
	roomKey := utils.AnyToString(roomId)
	roomData, ok := Room.Load(roomKey)
	if !ok {
		return fmt.Errorf("房间不存在")
	}
	roomDataObj, ok = roomData.(*entity.RoomState)
	if !ok {
		return fmt.Errorf("房间不存在")
	}

	roomDataObj.State = -1
	Room.Store(roomKey, roomDataObj)

	SetGameMatchStateDissolution(roomDataObj.GameId)
	return nil
}

// 房间状态修改为3
func RoomState3(roomId int64) *entity.RoomState {
	roomKey := utils.AnyToString(roomId)
	roomData, ok := Room.Load(roomKey)
	if !ok {
		return nil
	}
	roomDataObj, ok := roomData.(*entity.RoomState)
	if !ok {
		return nil
	}
	roomDataObj.State = 3
	// 更新数据
	Room.Store(roomKey, roomDataObj)
	return roomDataObj
}

func RoomSetGameId(roomId, gameId int64) *entity.RoomState {
	roomKey := utils.AnyToString(roomId)
	roomData, ok := Room.Load(roomKey)
	if !ok {
		return nil
	}
	roomDataObj, ok := roomData.(*entity.RoomState)
	if !ok {
		return nil
	}

	roomDataObj.GameId = gameId
	Room.Store(roomKey, roomDataObj)
	return roomDataObj
}

func RoomGetGameId(roomId int64) int64 {
	roomKey := utils.AnyToString(roomId)
	roomData, ok := Room.Load(roomKey)
	if !ok {
		return 0
	}
	roomDataObj, ok := roomData.(*entity.RoomState)
	if !ok {
		return 0
	}

	return roomDataObj.GameId
}
